var grammar = new Grammar();

/**
 * 存放全局的 Symbol 对象
 * @type {Array.<Symbol>}
 */
var input_symbol = [];
/**
 * 存放当前 Syntax 对象
 * @type {Array.<Syntax>}
 */
var input_syntax = [];

function Row(id, col_0) {
    this.id = id;
    this.col_0 = col_0;
    this.col_1 = '';
    this.col_2 = '';
}

var syntax_table = [];

/**
 *
 * @param {String} str
 */
Array.prototype.findSymbol = function (str) {
    for (var i = 0; i < this.length; ++i) {
        if (this[i].sym_exp == str)
            return this[i];
    }
    return undefined;
};

Array.prototype.findRowInTable = function (str) {
    for (var i = 0; i < this.length; ++i) {
        if (this[i].id.sym_exp === str)
            return this[i];
    }
    return undefined;
};

Array.prototype.findRow = function (str) {
    for (var i = 0; i < this.length; ++i) {
        if (this[i].sym_exp === str)
            return this[i];
    }
    return undefined;
};

/**
 * @param {string} str
 * @return {*} 该重写规则的
 */
var parse = function (str) {
    var curRow, syntax, contains, right, row_col_0 = [], bf = false;
    input_syntax.clear();
    syntax = str.split('::=');
    contains = input_symbol.findRow(syntax[0]);
    if (!contains) {
        contains = new Symbol(syntax[0]);
        curRow = new Row(contains, str);
        input_symbol.push(contains);
        syntax_table.push(curRow);
    } else {
        bf = curRow = syntax_table.findRowInTable(syntax[0]);
        if (!curRow) {
            curRow = new Row(contains, str);
            syntax_table.push(curRow);
        }
    }
    row_col_0.push(curRow.col_0);
    right = syntax[1].split('|');
    right.forEach(function (list) {
        var r = [];
        for (var i = 0; i < list.length; ++i) {
            var tmp = list.charAt(i);
            var c = input_symbol.findSymbol(tmp);
            if (!c) {
                c = new Symbol(tmp);
                input_symbol.push(c)
            }
            r.push(c);
        }
        input_syntax.push(new Syntax(contains, r));
        if (bf) {
            row_col_0.push(list);
        }
    });
    curRow.col_0 = row_col_0.join('|');
};

$(document).ready(function () {
    var synCheck = /^[A-Za-z]::=.+$/;
    var add_func = function () {
        var my_syn = $('.my-get-syn');
        var syn = my_syn.val();
        if (!syn || syn === '') {
            return;
        }
        var tmp = $('#my-syntax');
        if (!synCheck.test(syn)) {
            tmp.parent().addClass('has-error');
            tmp.focus();
        } else {
            tmp.parent().removeClass('has-error');
            parse(syn);
            grammar.addSyntax(input_syntax);
            var tbody = $('#my-grammar');
            tbody.find('tr').remove();
            syntax_table.forEach(function (every) {
                $('<tr><td>' + every.col_0 + '</td><td></td><td></td></tr>').appendTo(tbody);
            });
            my_syn.val('');
            tmp.focus();
        }
    };
    var start_func = function () {
        if (!grammar.execute()) {
            $('#my-warning').on('hidden.bs.modal', function () {
                reset_syn_func();
            }).modal();
            return;
        }
        var i, j;
        var comparison = grammar.getComparisonArray();
        // 处理 firstVt lastVt 表部分
        var tbody = $('#my-grammar');
        tbody.find('tr').remove();
        syntax_table.forEach(function (every) {
            every.col_1 = grammar.gra_firstVt.get(every.id).toString();
            every.col_2 = grammar.gra_lastVt.get(every.id).toString();
            $('<tr><td>' + every.col_0 + '</td><td>' + every.col_1 + '</td><td>' + every.col_2 + '</td></tr>').appendTo(tbody);
        });
        $('.my-step1-disable').attr('disabled', true);
        $('#my-ope-add').text('重置');
        // 关系信息的获取
        var my_gt_num = [], my_lt_num = [], my_eq_num = [];
        var my_gt_key = [], my_lt_key = [], my_eq_key = [];
        var my_gt_val = [], my_lt_val = [], my_eq_val = [];
        var val_gt_tmp, val_lt_tmp, val_eq_tmp;
        var num_gt_tmp, num_lt_tmp, num_eq_tmp;
        for (i = 1; i < comparison.length; ++i) {
            val_gt_tmp = [];
            val_lt_tmp = [];
            val_eq_tmp = [];
            num_gt_tmp = 0;
            num_lt_tmp = 0;
            num_eq_tmp = 0;
            my_gt_key.push(comparison[0][i]);
            my_lt_key.push(comparison[i][0]);
            my_eq_key.push(comparison[i][0]);
            for (j = 1; j < comparison.length; ++j) {
                if (comparison[j][i] === Compare.GT) {
                    val_gt_tmp.push(comparison[j][0]);
                    num_gt_tmp++;
                }
                if (comparison[i][j] === Compare.LT) {
                    val_lt_tmp.push(comparison[0][j]);
                    num_lt_tmp++;
                }
                if (comparison[i][j] === Compare.EQ) {
                    val_eq_tmp.push(comparison[0][j]);
                    num_eq_tmp++;
                }
            }
            my_gt_val.push(val_gt_tmp);
            my_gt_num.push(num_gt_tmp);
            my_lt_val.push(val_lt_tmp);
            my_lt_num.push(num_lt_tmp);
            my_eq_val.push(val_eq_tmp);
            my_eq_num.push(num_eq_tmp);
        }

        // 处理 relation 部分
        var my_gt = $('#my-gt-rel'), my_lt = $('#my-lt-rel'), my_eq = $('#my-eq-rel');
        for (i = 0; i < my_gt_key.length; ++i) {
            if (my_gt_num[i] > 0) {
                var n = [];
                for (j = 0; j < my_gt_val[i].length; ++j) {
                    n.push('<li class="list-group-item">', my_gt_val[i][j].sym_exp, ' ', Compare.GT, ' ', my_gt_key[i], '</li>');
                }
                $('<div class="panel panel-default">' +
                    '<div class="panel-heading" role="tab" id="my-gt-head' + i + '">' +
                    '<span class="panel-title"><a role="button" data-toggle="collapse" data-parent="#my-gt-rel" ' +
                    'href="#my-gt-collapse' + i + '" aria-expanded="false" aria-controls="my-gt-collapse' + i + '">' +
                    '<span class="badge">' + my_gt_num[i] + '</span> &gt; ' + my_gt_key[i] + '</a></span></div>' +
                    '<div id="my-gt-collapse' + i + '" class="panel-collapse collapse" role="tabpanel" ' +
                    'aria-labelledby="my-gt-head' + i + '"><div class="panel-body"><ul class="list-group">' +
                    n.join('') + '</ul></div></div></div>').appendTo(my_gt);
            }
        }
        for (i = 0; i < my_lt_key.length; ++i) {
            if (my_lt_num[i] > 0) {
                n = [];
                for (j = 0; j < my_lt_val[i].length; ++j) {
                    n.push('<li class="list-group-item">', my_lt_key[i], ' ', Compare.LT, ' ', my_lt_val[i][j].sym_exp, '</li>');
                }
                $('<div class="panel panel-default">' +
                    '<div class="panel-heading" role="tab" id="my-lt-head' + i + '">' +
                    '<span class="panel-title"><a role="button" data-toggle="collapse" data-parent="#my-lt-rel" ' +
                    'href="#my-lt-collapse' + i + '" aria-expanded="false" aria-controls="my-lt-collapse' + i + '">' +
                    my_lt_key[i] + ' &lt; ' + '<span class="badge">' + my_lt_num[i] + '</span>' + '</a></span></div>' +
                    '<div id="my-lt-collapse' + i + '" class="panel-collapse collapse" role="tabpanel" ' +
                    'aria-labelledby="my-lt-head' + i + '"><div class="panel-body"><ul class="list-group">' +
                    n.join('') + '</ul></div></div></div>').appendTo(my_lt);
            }
        }
        n = [];
        for (i = 0; i < my_eq_key.length; ++i) {
            if (my_eq_num[i] > 0) {
                for (j = 0; j < my_eq_val[i].length; ++j) {
                    n.push('<li class="list-group-item">', my_eq_key[i], ' ', Compare.EQ, ' ', my_eq_val[i][j].sym_exp, '</li>');
                }
            }
        }
        $('<ul class="list-group">' + n.join('') + '</ul>').appendTo(my_eq);
        // 处理 算符优先矩阵 部分
        var matrix = $('#my-ope-matrix');
        n = [];
        n.push('<tr><th></th>');
        for (i = 1; i < comparison[0].length; ++i) {
            n.push('<th>', comparison[0][i].sym_exp, '</th>');
        }
        n.push('</tr>');
        for (i = 1; i < comparison.length; ++i) {
            n.push('<tr><th>', comparison[i][0].sym_exp, '</th>');
            for (j = 1; j < comparison[i].length; ++j) {
                n.push('<td>', comparison[i][j], '</td>');
            }
            n.push('</tr>')
        }
        $(n.join('')).appendTo(matrix);
        $('#sen').attr('disabled', false);
        $('.my-ope-identify').attr('disabled', false);
        $('.my-ope-identify-addon').attr('disabled', false);
    };
    var reset_syn_func = function () {
        location.reload();
    };
    var identify_func = function () {
        var tmp = $('#sen'), inp = tmp.val(), i, j, input = [], tmp2;
        for (i = 0; i < inp.length; ++i) {
            tmp2 = input_symbol.findSymbol(inp.charAt(i));
            if (!tmp2) break;
            input.push(tmp2);
        }
        if (!tmp2) {
            tmp.parent().addClass('has-error');
            $('.my-label').text('匹配失败');
            return;
        } else {
            tmp.parent().removeClass('has-error');
        }
        grammar.unit(0, [], undefined, input);
        var tb = $('.my-process'), n = [], row;
        tb.find('tr').remove();
        for (i = 0; i < grammar.gra_table.length; ++i) {
            row = grammar.gra_table[i];
            n.push('<tr><td>', i, '</td><td>#');
            if (row.stack.length !== 0) {
                for (j = 0; j < row.stack.length; ++j) {
                    if (row.stack[j].sym_vt) {
                        n.push(row.stack[j].sym_exp);
                    }
                    else {
                        n.push('N');
                    }
                }
            }
            n.push('</td><td>', row.relation, '</td><td>');
            if (!row.next) n.push('#');
            else n.push(row.next.sym_exp);
            n.push('</td><td>');
            if (row.input.length !== 0) {
                for (j = 0; j < row.input.length; ++j) {
                    n.push(row.input[j].sym_exp);
                }
                n.push('#');
            } else {
                if (!!row.next) n.push('#');
            }
            n.push('</td><td>');
            if (row.phrase.length !== 0) {
                for (j = 0; j < row.phrase.length; ++j) {
                    if (row.phrase[j].sym_vt) {
                        n.push(row.phrase[j].sym_exp);
                    }
                    else {
                        n.push('N');
                    }
                }
            }
            n.push('</td></tr>')
        }
        $(n.join('')).appendTo(tb);
        if (!grammar.gra_succeed) {
            tmp.parent().addClass('has-error');
            $('.my-label').text('匹配失败');
        }
        else {
            tmp.parent().addClass('has-success');
            $('.my-label').text('匹配成功');
        }
    };

    $('#my-syntax').bind('keyup', function (event) {
        if (event.keyCode === 13) {
            if ($('#my-ope-add').text() === '添加') {
                var val = $('#my-syntax').val();
                if (!val || val === '') start_func();
                else add_func();
            } else {
                reset_syn_func();
            }
        }
        if (event.keyCode !== 8) {
            var th = $(this), s = th.val();
            if (/^[a-zA-Z][:]?[:]?$/.test(s))
                th.val(s.charAt(0) + '::=');
        }
    });
    $('#my-ope-add').click(function () {
        if ($(this).text() === '添加') add_func();
        else reset_syn_func();
    });
    $('.my-ope-add').click(add_func);
    $('.my-ope-reset-syn').click(reset_syn_func);
    $('.my-ope-start').click(start_func);
    $('.my-ope-identify').click(identify_func);
    $('#sen').bind('keyup', function (e) {
        if (e.keyCode === 13) {
            identify_func();
        }
    });
});